package cc.telecomdigital.tdstock.Services;

import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;

import cc.telecomdigital.tdstock.Framework.UniqueItem.DeviceInfo;
import cc.telecomdigital.tdstock.Framework.UniqueItem.TDStockLog;

import android.content.Context;

//Provide a Account Login feature, which we obtain the session key to performs our action.
public class LS_Authentication
{
	static public class LS_Authentication_Result
	{
		public String	errorMessage;
		public String	statusCode;
		/** The displaymessage for user, such as download **/
		public String  linkCaption;
		/** The message to represent the link caption, maybe a URL address **/
		public String  linkContent;

		public LS_Authentication_Result( String iStatus, String iErrorMessage, 
								   String iLinkCaption, String iLinkContent)
		{
			statusCode = iStatus;
			errorMessage = iErrorMessage;
			linkCaption   = iLinkCaption;
			linkContent  = iLinkContent;
		}

		public LS_Authentication_Result( LS_Authentication_Result iHost)
		{
			statusCode   = iHost.statusCode;
			errorMessage = iHost.errorMessage;
			linkCaption  = iHost.linkCaption;
			linkContent  = iHost.linkContent;
		}
		
		public void Flush()
		{
			statusCode   = "";
			errorMessage = "";
			linkCaption  = "";
			linkContent  = "";			
		}
	}

	public class LS_Authentication_ResultExt extends LS_Authentication_Result
	{
		public String accountNumber, sessionKey;
		public String svcPlan, svcFlag;
		public String horseMsg, footballMsg;

		public LS_Authentication_ResultExt()
		{
			super("", "", "", "");
			accountNumber = "";
			sessionKey = "";
			svcPlan = "";
			svcFlag = "";	
			horseMsg = "";
			footballMsg = "";			
		}
		
		
		/**
		 * @param iStatus       - Status from server, a digit type
		 * @param iErrorMessage - Message that display to user
		 * @param iLinkCaption  - The LinkTag is a tag that works behind
		 * @param iLineContent  - The message that represent the action of linkTag, such as download
		 */
		public LS_Authentication_ResultExt(String iStatus, String iErrorMessage, String iLinkCaption, String iLineContent)
		{
			super(iStatus, iErrorMessage, iLinkCaption, iLineContent);
			accountNumber = "";
			sessionKey = "";
			svcPlan = "";
			svcFlag = "";	
			horseMsg = "";
			footballMsg = "";			
			
		}		
		
		public void AddAccountInfo(String iAccountNo, String iSessionKey)
		{
			accountNumber = iAccountNo;
			sessionKey    = iSessionKey;
		}
		
		public void AddServiceInfo(String iSvcPlan, String iSvcFlag)
		{
			svcPlan = iSvcPlan;
			svcFlag = iSvcPlan;
		}
		
		public void AddPromotionMessage(String iHorseMsg, String iFBMsg)
		{
			horseMsg = iHorseMsg;
			footballMsg = iFBMsg;
		}
	}
	
	// The purpose is to blind the account number and sessionKey to keep within our
	// LS_UserClient module
	static public interface ILS_Authentication_Report
	{
		void ILS_Authentication_Response(boolean iSuccessfulSend,
				LS_Authentication_ResultExt iResult);
	}

	private final String	LOG_TAG		= "LS_Authentication";
	// Login Address
	private String			urlString;
	@SuppressWarnings("unused")	
	private String			urlPort;
	private final int		SOCKET_TIMEOUT		= 30000;
	private final int		CONNECT_TIMEOUT	= 30000;
	private Context		ownerContext;
	private final boolean   debugMode = false;

	private final int              trialMax = 2;
	public LS_Authentication(Context iOwner, String iURL, String iPort)
	{
		ownerContext = iOwner;
		urlString    = iURL;
		urlPort      = iPort;
	}

	private ILS_Authentication_Report	reporter;

	public synchronized void RequestLogin(ILS_Authentication_Report iLoginResponse)
	{
		reporter = iLoginResponse;
		// Start the Thread
		Thread internalThreadObj = new Thread()
		{
			//Send request thru a thread
			@Override
			public void run()
			{	
				//If no network, we could skip the next
				if (DeviceInfo.IsNetworkAvailable(ownerContext) == false)
				{
					if (reporter != null)
						reporter.ILS_Authentication_Response(false,
								new LS_Authentication_ResultExt());
					return;
				}
				
				int 					   trialCount;				
				HttpClient 			   client;
				HttpGet 				   request;
				HttpParams 			   modParams;
				LS_Authentication_ResultExt result;
				
				client = new DefaultHttpClient();
				request = new HttpGet(urlString);
				modParams = request.getParams();

				// Change the setting
				HttpConnectionParams.setSoTimeout(modParams, SOCKET_TIMEOUT);
				HttpConnectionParams.setConnectionTimeout(modParams,CONNECT_TIMEOUT);
				request.setParams(modParams);				
				trialCount = 0;
				while(true)
				{					
					if (debugMode)
						TDStockLog.i(LOG_TAG, "Enter to Send Data");
					result = SendDataSub(client, request);
					//If we did not get the require login information
					if ( ((result.accountNumber.equals("")) && (result.sessionKey.equals("")))
						&& ((result.statusCode.equals("")) || (result.errorMessage.equals(""))))
					{
						++trialCount;
						if (trialCount < trialMax)
						{
							if (debugMode)
								TDStockLog.i(LOG_TAG, "SendRequest: Retry performed: " + trialCount);
							try
							{
								sleep(500);
							}
							catch(Exception ex)
							{
								TDStockLog.e(LOG_TAG, "SendRequest: Ex=" + ex.toString());
							}							
							continue;
						}
					}
					
					if (reporter != null)
						reporter.ILS_Authentication_Response(true, result);				
					break;
				}
			}
		};
		internalThreadObj.setName(LOG_TAG);
		internalThreadObj.start();
	}
	
	private LS_Authentication_ResultExt SendDataSub(HttpClient iClient, HttpGet iRequest)
	{
		LS_Authentication_ResultExt result;

		//prepare for the result			
		String sessionKey, accountNo, statCode, errorMsg;
		String svcPlan, svcFlags, sportMsg, horseMsg;
		String linkCaption, linkContent;
		
		sessionKey = "";
		accountNo = "";
		statCode = "";
		errorMsg = "";
		svcPlan = "";
		svcFlags = "";
		sportMsg = "";
		horseMsg = "";
		linkCaption = "";
		linkContent = "";
		//Now perform the sending and obtaining the expected data		
		try
		{
			HttpResponse webResponse;

			StringBuffer contentString;

			if (debugMode)
				TDStockLog.i(LOG_TAG, "HttpClient Request Enter");
			webResponse = iClient.execute(iRequest);
			if ((webResponse == null) || (webResponse.getStatusLine().getStatusCode()!= HttpStatus.SC_OK ))
				webResponse.getEntity().getContent().close();
			else
			{
				contentString = CommunicTools.GetWebResponseInStringBuffer(webResponse);						
				
				//Really cheap way of getting the data
				sessionKey = CommunicTools.FindXMLStringContent(contentString, "SessionID");
				accountNo  = CommunicTools.FindXMLStringContent(contentString, "Account");	
				//			0 Success
				//			1 invalid account.
				//			2 invalid svc_no
				//			3 invalid status
				//			4 invalid login_name or account
				//			5 invalid password
				//			6 invalid model
				//			7 invalid charge
				//			9 SQL Exception
				statCode = CommunicTools.FindXMLStringContent(contentString, "Status");
				errorMsg  = CommunicTools.FindXMLStringContent(contentString, "ErrorMessage");
	
				svcPlan  = CommunicTools.FindXMLStringContent(contentString, "SvcPlan");
				svcFlags = CommunicTools.FindXMLStringContent(contentString, "SvcFlags");
				sportMsg = CommunicTools.FindXMLStringContent(contentString, "SportsPromotionMessage");
				horseMsg = CommunicTools.FindXMLStringContent(contentString, "HorsePromotionMessage");
				linkCaption = CommunicTools.FindXMLStringContent(contentString,   "UpgradeUrlCaption");
				linkContent = CommunicTools.FindXMLStringContent(contentString,   "UpgradeUrl");				
			}
		}
		catch (ClientProtocolException e)
		{
			e.printStackTrace();
			TDStockLog.e(LOG_TAG, "SendDataSun=>ClientProtocolException: " + e.toString());
		}
		catch (IOException e)
		{
			e.printStackTrace();
			TDStockLog.e(LOG_TAG, "SendDataSun=>IOException: " + e.toString());
		}
		catch (Exception e)
		{
			e.printStackTrace();
			TDStockLog.e(LOG_TAG, "SendDataSun=>Exception: " + e.toString());
		}

		result = new LS_Authentication_ResultExt(statCode, errorMsg, linkCaption, linkContent);
		result.AddAccountInfo(accountNo, sessionKey);
		result.AddServiceInfo(svcPlan, svcFlags);
		result.AddPromotionMessage(horseMsg, sportMsg);
		
		if (debugMode)
			TDStockLog.i(LOG_TAG, "SendDataSun: Report of data");
		
		return result;
	}
	
}
